#include <iostream>
using namespace std;
#include <signal.h>
#include <unistd.h>
#include <cassert>
#include <cstring>

//使用signal自定义信号捕捉行为
// void sigcb(int signo)
// {
//     cout<<"触发:"<<signo<<"信号"<<endl;
// }

// int main()
// {
//     signal(SIGINT,sigcb);
//     while(true)
//     {
//         cout<<"进程运行中..."<<endl;
//         sleep(1);
//     }
//     return 0;
// }

//使用信号集修改信号屏蔽字
// int main()
// {
//     sigset_t set;
//     sigset_t oset;
//     sigemptyset(&set);
//     sigemptyset(&oset);
//     sigaddset(&set,2); //设置2和40信号
//     sigaddset(&set,40); 

//     sigprocmask(SIG_SETMASK,&set,&oset); //设置信号屏蔽字

//     while(true)
//     {
//         cout<<getpid()<<"进程运行中..."<<endl;
//         sleep(1);
//     }
//     return 0;
// }

// void print(sigset_t* sgset)
// {
//     for(int i = 1;i<32;++i)
//     {
//         if(sigismember(sgset,i)) cout<<"1";
//         else cout<<"0";
//     }
//     cout<<endl;
// }

//sigpending查看被屏蔽为处理的信号 再恢复此信号
// int main()
// {
//     signal(SIGINT,sigcb); //重定向2信号为sigcb
//     signal(SIGQUIT,sigcb); //重定向2信号为sigcb

//     sigset_t set; //设置两个信号集
//     sigset_t oset;
//     sigemptyset(&set); //初始化两个信号集
//     sigemptyset(&oset);

//     sigaddset(&set,2); //设置2号信号阻塞
//     sigaddset(&set,3); //设置3号信号阻塞
//     sigprocmask(SIG_BLOCK,&set,&oset); //添加阻塞信号

//     int cnt = 0;
//     while(true)
//     {
//         sigset_t pending;
//         sigemptyset(&pending);
//         int n = sigpending(&pending); //获取当前的pending表
//         assert(n == 0);
//         (void)n;
//         print(&pending);
//         sleep(1);

//         if(cnt++ == 10)
//         {
//             sigprocmask(SIG_UNBLOCK,&set,&oset); //10秒以后将阻塞信号解除
//         } //观察到的现象是无论是先发送2号信号还是先发送3号信号，总是先处理3号信号
//     }

//     return 0;
// }


//hander方法查看执行捕捉动作时的pending表
// void hander(int signo)
// {
//     cout<<"收到:"<<signo<<"信号"<<endl;
//     cout<<"hander内pending表为:";
//     sigset_t pending;
//     sigemptyset(&pending);
//     sigpending(&pending); //获取当前的pending表
//     print(&pending);
// }

//通过sigpending验证信号是在处理捕捉动作前清0还是执行后清0
// int main()
// {
//     signal(2,hander);

//     int i = 20;
//     while(--i)
//     {
//         cout<<"进程运行中..."<<endl;
//         sleep(1);
//     }
//     return 0;
// }//结论：信号是在执行自定义捕捉动作前清0的

//使用sigaction函数和对象
// void sigcb(int signo)
// {
//     cout<<"触发:"<<signo<<"信号"<<endl;
// }

// int main()
// {
//     struct sigaction act;
//     struct sigaction oact;
//     memset(&act,0,sizeof(act)); //初始化
//     memset(&oact,0,sizeof(oact)); 

//     act.sa_flags = 0; //设置为0
//     act.sa_handler = sigcb;

//     sigaction(SIGINT,&act,&oact); //设置2号信号

//     while(true)
//     {
//         cout<<"进程运行中..."<<endl;
//         sleep(1);
//     }

//     return 0;
// }

// void hander(int signo)
// {
//     cout<<"收到:"<<signo<<"信号"<<endl;
//     int i = 20;
//     while(i--)
//     {
//         cout<<"hander内pending表为:";
//         sigset_t pending;
//         sigemptyset(&pending);
//         sigpending(&pending); //获取当前的pending表
//         print(&pending);
//         sleep(1);
//     }
// }

// //使用sigaction修改指定信号的处理动作
// int main()
// {
//     struct sigaction act;
//     struct sigaction oact;
//     memset(&act,0,sizeof(act)); //初始化
//     memset(&oact,0,sizeof(oact)); 

//     act.sa_flags = 0; //设置为0
//     act.sa_handler = hander;

//     sigemptyset(&act.sa_mask); //初始化阻塞信号集
//     sigaddset(&act.sa_mask,SIGQUIT); //使该信号处理时阻塞3 4 5 9信号
//     sigaddset(&act.sa_mask,SIGILL);
//     sigaddset(&act.sa_mask,SIGTRAP);
//     sigaddset(&act.sa_mask,SIGKILL); //9号信号无法被屏蔽

//     //屏蔽以上信号以后，当处理当前信号时，收到以上信号会被阻塞，直到处理完当前信号才会解除

//     sigaction(SIGINT,&act,&oact); //设置2号信号处理动作

//     while(true);

//     return 0;
// }